package indi.free.widgets.custom_recycler_view;

import android.content.Context;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

import indi.free.widgets.R;

/**
 * @author L.B
 */
public abstract class BasePagerRecyclerAdapter<T> extends RecyclerView.Adapter<RecyclerViewHolder> {

    protected final List<T> mData;
    protected final Context mContext;
    protected LayoutInflater mInflater;
    private OnItemClickListener mClickListener;
    private OnLoadMoreListener mOnLoadMoreListener;

    private RecyclerView mRecyclerView;
    private LinearLayoutManager mManager;


    private final static int ITEM_TYPE_FOOTER_LAYOUT_ID = R.layout.item_list_footer;
    private final static int ITEM_TYPE_FOOTER = -1;
    private final static int ITEM_TYPE_NORMAL = 0;

    public final static int FOOTER_STATUS_OVER = 0;
    public final static int FOOTER_STATUS_LOADING = 1;
    public final static int FOOTER_STATUS_RELOAD = 2;

    private final static int FOOTER_LOADING_TIME = 500;


    private int footerStatus;


    public void updateFooterStatusByLoad(int footerStatus) {

        this.footerStatus = footerStatus;
        this.isLoadingMore = false;

        if (this.footerStatus == FOOTER_STATUS_OVER) {
            notifyItemRemoved(mData.size());
        } else {
            notifyItemChanged(mData.size());
        }

    }

    public void updateFooterStatusByRefresh(int footerStatus) {

        if (this.footerStatus == footerStatus) {
            return;
        }

        if (footerStatus == FOOTER_STATUS_OVER) {
            notifyItemRemoved(mData.size());
        } else {
            notifyItemChanged(mData.size());
        }

        this.footerStatus = footerStatus;

    }


    private boolean isLoadingMore;


    private void invokeOuterOnLoadMore() {
        if (!isLoadingMore && null != mOnLoadMoreListener && footerStatus == FOOTER_STATUS_LOADING) {
            isLoadingMore = true;
            mOnLoadMoreListener.onLoadMore();
        }
    }


    public BasePagerRecyclerAdapter(Context ctx, RecyclerView recyclerView, List<T> list) {
        mData = (list != null) ? list : new ArrayList<T>();
        mContext = ctx;
        mInflater = LayoutInflater.from(ctx);
        mRecyclerView = recyclerView;
        mManager = new LinearLayoutManager(ctx);
        mRecyclerView.setLayoutManager(mManager);
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                if (dy > 0 && mManager.findLastVisibleItemPosition() == mManager.getItemCount() - 1) {
                    Log.d("BasePagerRvAdapter", "invoke");
                    invokeOuterOnLoadMore();
                }
            }
        });

    }


    @Override
    public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        RecyclerViewHolder holder = null;
        Log.d("FJR", "view type = " + viewType);
        if (viewType != ITEM_TYPE_FOOTER) {

            holder = new RecyclerViewHolder(mContext, mInflater.inflate(getItemLayoutId(), parent, false));

            if (mClickListener != null) {
                final RecyclerViewHolder finalHolder = holder;
                holder.itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mClickListener.onItemClick(finalHolder.itemView, finalHolder.getLayoutPosition());
                    }
                });
            }

        } else {
            holder = new RecyclerViewHolder(mContext, mInflater.inflate(ITEM_TYPE_FOOTER_LAYOUT_ID,
                    parent, false));
            if (mOnLoadMoreListener != null) {
                final RecyclerViewHolder finalHolder1 = holder;
                holder.itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        finalHolder1.itemView.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {

                                if (isLoadingMore)
                                    return;

                                isLoadingMore = true;
                                footerStatus = FOOTER_STATUS_LOADING;
                                notifyItemChanged(getItemCount() - 1);
                                v.postDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                                        mOnLoadMoreListener.onLoadMore();
                                    }
                                }, FOOTER_LOADING_TIME);
                            }
                        });
                    }
                });
            }
        }
        return holder;
    }

    @Override
    public void onBindViewHolder(RecyclerViewHolder holder, int position) {

        if(mData.size() <= 0){
            bindData(holder, position,null);
            return;
        }

        if (position != mData.size()&&mData.size()>0) {
            bindData(holder, position, mData.get(position));
        } else {
            renderFooter(holder);
        }
    }

    private void renderFooter(RecyclerViewHolder holder) {
        if (FOOTER_STATUS_LOADING == footerStatus) {
            holder.getView(R.id.btn_reload).setVisibility(View.INVISIBLE);
            holder.getView(R.id.ll_loading_container).setVisibility(View.VISIBLE);
        } else if (FOOTER_STATUS_RELOAD == footerStatus) {
            holder.getView(R.id.btn_reload).setVisibility(View.VISIBLE);
            holder.getView(R.id.ll_loading_container).setVisibility(View.INVISIBLE);
        }
    }

    public T getItem(int position) {
        return mData.get(position);
    }

    @Override
    public int getItemViewType(int position) {
        if (position == mData.size()) {
            return ITEM_TYPE_FOOTER;
        } else {
            return ITEM_TYPE_NORMAL;
        }
    }

    @Override
    public int getItemCount() {
        if (footerStatus == FOOTER_STATUS_OVER) {
            return mData.size();
        } else {
            return mData.size() + 1;
        }
    }

    public void addMoreData(List<T> moreData, boolean hasMore) {

        isLoadingMore = false;

        int oriDataSize = mData.size();
        int moreDataSize = moreData.size();

        mData.addAll(moreData);
        if (hasMore) {
            notifyItemRangeInserted(oriDataSize, moreDataSize);
        } else {
            updateFooterStatusByLoad(FOOTER_STATUS_OVER);
        }
    }

    public void refreshData(List<T> newData, boolean hasMore) {

        if (newData != null) {
            mData.clear();
            mData.addAll(newData);
            notifyDataSetChanged();
        }

        if (!hasMore) {
            updateFooterStatusByRefresh(FOOTER_STATUS_OVER);
        } else {
            updateFooterStatusByRefresh(FOOTER_STATUS_LOADING);
        }

    }

    public void add(int pos, T item) {
        mData.add(pos, item);
        notifyItemInserted(pos);
    }

    public void delete(int pos) {
        mData.remove(pos);
        notifyItemRemoved(pos);
    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        mClickListener = listener;
    }

    public void setmOnLoadMoreListener(OnLoadMoreListener mOnLoadMoreListener) {
        this.mOnLoadMoreListener = mOnLoadMoreListener;
    }

    abstract public int getItemLayoutId();

    abstract public void bindData(RecyclerViewHolder holder, int position, T item);

    public interface OnItemClickListener {
        public void onItemClick(View itemView, int pos);
    }

    public interface OnItemLongClickListener {
        public void onItemLongClick(View itemView, int pos);
    }

    public interface OnLoadMoreListener {
        public void onLoadMore();
    }

}
